package com.church.elim.controller.rest;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

import com.church.elim.domain.Children;
import com.church.elim.domain.Parishioner;
import com.church.elim.domain.Person;
import com.church.elim.repository.ChildrenRepository;
import com.church.elim.repository.PersonRepository;
import com.church.elim.service.ChildAlreadyExistsException;
import com.church.elim.service.ChildrenService;
import com.church.elim.service.PersonService;

@Controller
public class RESTPersonController {
	/* Returns a list with the names of all persons
	 * 
	 */
	@Autowired 
	PersonRepository personRepo;
	@Autowired 
	ChildrenRepository childrenRepo;
	@Autowired 
	ChildrenService childrenService;
	@Autowired 
	PersonService personService;

	@RequestMapping(value = "/rest/persons/names", method = RequestMethod.GET)
	public @ResponseBody
	List<Person> getPersonsNames(HttpServletResponse response, HttpServletRequest request, Model uiModel) {
		List<Person> persons = personRepo.findNames();
		return persons;
	}

	@RequestMapping(value = "/rest/persons/{id}", method = RequestMethod.GET)
	public @ResponseBody
	Person getPerson(@PathVariable("id") Long id,HttpServletResponse response, HttpServletRequest request, Model uiModel) {
		Person person = personRepo.findOne(id);
		return person;
	}

	@RequestMapping(value = "/rest/persons/{id}/children", method = RequestMethod.GET)
	public @ResponseBody
	List<Person> getParishionersNames(@PathVariable("id") Long id,HttpServletResponse response, HttpServletRequest request, Model uiModel) {
		List<Person> children = new ArrayList<Person>();
		if(personRepo.exists(id)){
			Person person= personRepo.findOne(id);
			for(Children c: person.getChildren()){
				children.add(c.getChild());
			}
		}
		return children;
	}

	/* Adds a child to a person children list and returns the added children entity */
	@RequestMapping(value = "/rest/persons/{id}/children", method = RequestMethod.POST,
			produces="application/json")
	public @ResponseBody
	Children addChildrenById(@PathVariable("id") Long parentId,@RequestBody Long childId,HttpServletResponse response, HttpServletRequest request, Model uiModel) throws IOException {
		String message="";
		Children children = null;
		Children childrenEntity = null;
		try{
			if(parentId != null && childId != null){
				children = new Children();
				System.out.println("Children++");
				Person parent = personRepo.findOne(parentId);
				System.out.println(parent.toString());
				Person child = personRepo.findOne(childId);
				System.out.println(child.toString());
				children.setParent(parent);
				children.setChild(child);
				if(childrenService.exists(children)){
					throw new Exception("Parent with id " + parentId + 
							" already has child with id "+ childId + "!");
				}
				childrenEntity = childrenRepo.saveAndFlush(children);
				message="Successfully added children"+childId+"!";
				response.setStatus(HttpServletResponse.SC_OK);
			}
		}catch(Exception e){
			message = e.toString();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,message);
			return null;
		}
		return childrenEntity;
	}

	/* Adds a child to a person children list and returns the added children entity */
	@RequestMapping(value = "/rest/persons/{id}/children/add", method = RequestMethod.POST,
			produces="application/json")
	public @ResponseBody
	Children addChildrenByName(@PathVariable("id") Long parentId,@RequestBody String childName,HttpServletResponse response, HttpServletRequest request, Model uiModel) throws IOException {
		String message="";
		Children children = null;
		try{
			children = personService.addChild(parentId, childName);
			message="Successfully added children"+childName+"!";
			response.setStatus(HttpServletResponse.SC_OK);
		}catch(Exception e){
			message = e.toString();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,message);
			return null;
		}
		return children;
	}

	/* Adds a child to a person children list and returns the added children entity */
	@RequestMapping(value = "/rest/persons/{id}/children/add-list", method = RequestMethod.POST,
			produces="application/json")
	public @ResponseBody
	Children addChildrenListByName(@PathVariable("id") Long parentId,@RequestBody List<String> childNames,HttpServletResponse response, HttpServletRequest request, Model uiModel) throws IOException {
		String message="";
		Children children = null;
		try{
			for(String childName: childNames){
				try{
					children = personService.addChild(parentId, childName);
				}catch (ChildAlreadyExistsException e){
					// TODO
				}
			}
			response.setStatus(HttpServletResponse.SC_OK);
		}catch(Exception e){
			message = e.toString();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,message);
			return null;
		}
		return children;
	}
	/* Adds a child to a person children list and returns the added children entity */
	@RequestMapping(value = "/rest/persons/{id}/children/delete", method = RequestMethod.POST)
	public @ResponseBody
	String deleteChildren(@PathVariable("id") Long parentId,@RequestBody Long childId,HttpServletResponse response, HttpServletRequest request, Model uiModel) throws IOException {
		String message="";
		Children children = null;
		Children childrenEntity = null;
		try{
			if(parentId != null && childId != null){
				children = new Children();
				Person parent = personRepo.findOne(parentId);
				Person child = personRepo.findOne(childId);
				children.setParent(parent);
				children.setChild(child);
				List<Children> childrens = childrenRepo.findByParentIdAndChildId(parentId, childId);
				if(childrens!=null){
					for(Children entity: childrens)
						childrenRepo.delete(entity);
				}else{
					response.setStatus(HttpServletResponse.SC_OK);
					return "Child " + childId + " does not exist in the database!";
				}
				response.setStatus(HttpServletResponse.SC_OK);
			}
		}catch(Exception e){
			message = e.toString();
			response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,message);
			return null;
		}
		return "Succesfully removed child " + childId + "!";
	}
}
